package com.zatech.cgnci.project.base.utils;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Pattern;

/**
 * 全局验证工具类
 *
 * @author Yingdf
 */
public class VerifyUtils {

    /**
     * 验证对象是否为空或者内容是否为空
     *
     * @param obj 验证对象
     * @return 为空返回 true 否则返回 false
     */
    public static boolean isEmpty(Object obj) {
        // FIRST CHECK
        if (null == obj) {
            return true;
        }
        // OTHER CHECK
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        } else if (obj instanceof Map) {
            return ((Map<?, ?>) obj).isEmpty();
        } else if (obj instanceof Iterable) {
            return !((Iterable<?>) obj).iterator().hasNext();
        } else if (obj instanceof Iterator) {
            return !((Iterator<?>) obj).hasNext();
        } else if (isArray(obj)) {
            return 0 == Array.getLength(obj);
        }
        // OTHER TYPE NOT NULL
        return false;
    }

    /**
     * 验证对象是否为空
     *
     * @param obj 验证对象
     * @return 为空返回 true 否则返回 false
     */
    public static boolean isNull(Object obj) {
        return null == obj;
    }

    /**
     * 验证对象是否不为空
     *
     * @param obj 验证对象
     * @return 不为空返回 true 否则返回 false
     */
    public static boolean isNotNull(Object obj) {
        return null != obj;
    }

    /**
     * 验证对象是否不为空
     *
     * @param obj 验证对象
     * @return 不为空返回 true 否则返回 false
     */
    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    /**
     * 如果给定对象为{@code null}返回默认值
     *
     * @param <T>          对象类型
     * @param obj          被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}返回的默认值，可以为{@code null}
     * @return 被检查对象为{@code null}返回默认值，否则返回原值
     */
//    public static <T> T defaultIfNull(final T obj, final T defaultValue) {
//        return isNotNull(obj) ? obj : defaultValue;
//    }

    /**
     * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值
     *
     * @param source Object 类型对象
     * @param handle 自定义的处理方法
     * @param <T>    被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     */
//    public static <T> T defaultIfNull(T source, Supplier<? extends T> handle) {
//        return isNotNull(source) ? source : handle.get();
//    }

    /**
     * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值
     *
     * @param source Object 类型对象
     * @param handle 自定义的处理方法
     * @param <T>    被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     */
//    public static <S, T> T applyIfNull(S source, Function<S, T> handle) {
//        if (isNotNull(source)) {
//            return handle.apply(source);
//        }
//        return null;
//    }

    /**
     * 对象为空返回 handle 内容
     *
     * @param obj          对象
     * @param defaultValue 默认内容
     * @return 对象为空返回 handle 内容
     */
//    public static <T> T defaultIfEmpty(T obj, final T defaultValue) {
//        return isNotEmpty(obj) ? obj : defaultValue;
//    }

    /**
     * 对象为空返回 handle 内容
     *
     * @param obj    对象
     * @param handle 自定义的处理方法
     * @return 对象为空返回 handle 内容
     */
//    public static <T> T defaultIfEmpty(T obj, Supplier<? extends T> handle) {
//        return isNotEmpty(obj) ? obj : handle.get();
//    }

    /**
     * 对象是否为数组对象
     *
     * @param obj 对象
     * @return 是否为数组对象，如果为{@code null} 返回false
     */
    public static boolean isArray(Object obj) {
        if (null == obj) {
            return false;
        }
        return obj.getClass().isArray();
    }

    /**
     * 根据对象是否为空决定是否执行对应的表达式
     *
     * @param obj      对象
     * @param consumer 消费者
     * @param <T>      泛型
     */
    public static <T> void executeOrNull(T obj, Consumer<T> consumer) {
        executeOrFlag(VerifyUtils.isNotNull(obj), obj, consumer);
    }

    /**
     * 根据对象是否为 empty 决定是否执行对应的表达式
     *
     * @param obj      对象
     * @param consumer 消费者
     * @param <T>      泛型
     */
    public static <T> void executeOrEmpty(T obj, Consumer<T> consumer) {
        executeOrFlag(VerifyUtils.isNotEmpty(obj), obj, consumer);
    }

    /**
     * 根据对象是否为 empty 决定是否循环执行对应的表达式
     *
     * @param items    对象
     * @param consumer 消费者
     * @param <T>      泛型
     */
    public static <T> void forOrEmpty(Collection<T> items, Consumer<T> consumer) {
        forOrFlag(VerifyUtils.isNotEmpty(items), items, consumer);
    }

    /**
     * 是否执行对应的表达式
     *
     * @param items    对象
     * @param consumer 消费者
     * @param <T>      泛型
     */
    public static <T> void forOrFlag(boolean isExecute, Collection<T> items, Consumer<T> consumer) {
        if (isExecute) {
            items.forEach(consumer);
        }
    }

    /**
     * 是否执行对应的表达式
     *
     * @param obj      对象
     * @param consumer 消费者
     * @param <T>      泛型
     */
    public static <T> void executeOrFlag(boolean isExecute, T obj, Consumer<T> consumer) {
        if (isExecute) {
            consumer.accept(obj);
        }
    }

    /*
     * 判断是否为整数
     * @param str 传入的字符串
     * @return 是整数返回true,否则返回false
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

}
